package com.kevin.biz.code.service.impl;

import java.io.File;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.velocity.texen.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.kevin.biz.base.dao.BaseJdbcDao;
import com.kevin.biz.code.service.CodeService;
import com.kevin.utility.common.CamelCaseUtils;
import com.kevin.utility.common.ResourceUtil;
import com.kevin.utility.common.VelocityUtils;


@Service
public class CodeServiceImpl implements CodeService{
	private static final Logger logger = Logger.getLogger(CodeServiceImpl.class);
	
	@Autowired
	BaseJdbcDao baseJdbcDao;
	private static File[] fileNames = ResourceUtil.getFile("classpath:code/template/live");
	@Override
	public void createTemplate(String dataBaseName, String tableName, String module){
		String tables[] = tableName.split(",");
		for(String table: tables){
			createFile(dataBaseName, table, module);
		}
	}

	public void createFile(String dbName, String tableName, String module) {
		List<LinkedHashMap<String, String>> columns = getColumn(tableName, dbName);
		Map<String, Object> params = getParams(columns, dbName, tableName,module);
		String filepath = ResourceUtil.getPath("")+"\\src\\main\\java\\com\\vip\\sce\\biz\\"+module/*"E:\git\code\maven-parent\maven-web*/;
		for(int i=0;i<fileNames.length; i++){
			try{
				String desFile = null;
				String desDir = filepath+map.get(fileNames[i].getName());
				if(fileNames[i].getName().indexOf("js")> -1){
					desFile = desDir +CamelCaseUtils.toLowerCaseCamelCase(tableName) + fileNames[i].getName().replaceAll(".vm", "").replaceAll("vm", "");
				}else{
					desFile = desDir +CamelCaseUtils.toUpperCaseCamelCase(tableName)+ fileNames[i].getName().replaceAll(".vm", "").replaceAll("vm", "");
				}
				FileUtil.mkdir(desDir);
				VelocityUtils.merge("code/template/live/" + fileNames[i].getName(), params, desFile);
			}catch(Exception e){
				logger.error(e.getMessage(), e);
			}
		}
	}
	
	public Map<String, Object> getParams(List<LinkedHashMap<String, String>> columns, String dbName, String tableName, String module){
		String primaryKey = null;
		String primaryColumn = null;
		Map<String, Object> params = new HashMap<String, Object>();
		for(int i=0;i<columns.size();i++){
			LinkedHashMap<String, String> map = columns.get(i);
			if(StringUtils.isEmpty(primaryKey) && "PRI".equalsIgnoreCase(map.get("COLUMN_KEY").toString())){
				primaryKey = CamelCaseUtils.toLowerCaseCamelCase(map.get("COLUMN_NAME").toString());
				primaryColumn = map.get("COLUMN_NAME").toString();
				break;
			}
		}
		LinkedHashMap<String, String> table = getTable(tableName, dbName);
		params.put("dollarSign", "$"); 
		params.put("leftBrace", "{");
		params.put("rightBrace", "}");
		params.put("primaryColumn", primaryColumn);
		params.put("pointSign", ".");
		params.put("commentSign", "#");
		params.put("columns", columns);
		params.put("module", module);
		params.putAll(table);
		params.put("tableName", tableName);
		params.put("primaryKey", primaryKey);
		params.put("primaryKeyUpperCase", CamelCaseUtils.toUpperCaseCamelCase(primaryColumn));
		params.put("primaryColumn", primaryColumn);
		params.put("tableLowerCaseCamelCase", CamelCaseUtils.toLowerCaseCamelCase(tableName));
		params.put("tableUpperCaseCamelCase", CamelCaseUtils.toUpperCaseCamelCase(tableName));
		params.put("columnSize", columns.size());
		return params;
	}
	
	
	public List<LinkedHashMap<String, String>> getColumn(String tableName,String dataBaseName){
		String sql = "SELECT COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH,COLUMN_KEY, COLUMN_COMMENT from COLUMNS where TABLE_NAME = '"+  tableName + "' and TABLE_SCHEMA = '"+ dataBaseName +"'";
		List<LinkedHashMap<String, String>> list = baseJdbcDao.query(sql);
		
		for(int i=0;i<list.size();i++){
			LinkedHashMap<String, String> map = list.get(i);
			map.put("index", i+1+"");
			map.put("COLUMN_NAME_LOW_CASE_CAMEL_CASE", CamelCaseUtils.toLowerCaseCamelCase(map.get("COLUMN_NAME").toString()));
			map.put("COLUMN_NAME_UPPER_CASE_CAMEL_CASE", CamelCaseUtils.toUpperCaseCamelCase(map.get("COLUMN_NAME").toString()));
			
			String dataType = map.get("DATA_TYPE");
			if("int".equals(dataType)){
				map.put("DATA_TYPE", "INTEGER");
				map.put("clss", "Integer");
			}else if("bigint".equals(dataType)){
				map.put("DATA_TYPE", "INTEGER");
				map.put("clss", "Long");
			}else if("varchar".equalsIgnoreCase(dataType) || "char".equalsIgnoreCase(dataType)){
				map.put("DATA_TYPE", dataType.toUpperCase());
				map.put("clss", "String");
			}else if("timestamp".equalsIgnoreCase(dataType)){
				map.put("DATA_TYPE", dataType.toUpperCase());
				map.put("clss", "Date");
			}else if("double".equalsIgnoreCase(dataType)){
				map.put("DATA_TYPE", dataType.toUpperCase());
				map.put("clss", "Double");
			}else if("222".equalsIgnoreCase(dataType)){
				map.put("DATA_TYPE", dataType.toUpperCase());
				map.put("clss", "Boolean");
			}else{
				map.put("DATA_TYPE", dataType.toUpperCase());
				map.put("clss", "String");
			}
			logger.info("");
		}
		
		return list;
	}
	
	@Override
	public LinkedHashMap<String, String> getTable(String tableName, String dataBaseName){
		String sql = "SELECT * from `TABLES` where TABLE_NAME = '"+ tableName + "' and TABLE_SCHEMA = '"+ dataBaseName +"'";
		List<LinkedHashMap<String, String>> list = baseJdbcDao.query(sql);
		if(list.size() > 0){
			return list.get(0);
		}else {
			return null;
		}
	}
	
	
	private static Map<String,String> map = new HashMap<String,String>();
	static{
		map.put("Controller.java.vm", "/controller/");
		map.put("Dao.java.vm", "/dao/");
		map.put("Controller.java.vm", "/controller/");
		map.put("Service.java.vm", "/service/");
		map.put("ServiceImpl.java.vm", "/service/impl/");
		map.put("vm.java.vm", "/entity/");
		map.put("vm.js.vm", "/js/");
		map.put("vm.jsp.vm", "/page/");
		map.put("vm.xml.vm", "/mapper/");
	}
}
